package com.youkeyi.ddy.cloud.common.utils;

import org.apache.commons.lang.StringUtils;

import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * SystemDateUtils
 *
 * @Author liuxiawang
 * @Date 2019-12-19 10:42
 * @Location shenzhen.china
 */
public class SystemDateUtils {

    /**
     * 获取两个日期相隔几天
     */
    public static Long getEpochDays(Long startTimestamp, Long endTimestamp) {
        if (startTimestamp == null || endTimestamp == null) {
            return null;
        }
        LocalDateTime startLocalDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(startTimestamp), ZoneId.systemDefault());
        LocalDateTime entLocalDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(endTimestamp), ZoneId.systemDefault());
        return startLocalDateTime.toLocalDate().toEpochDay() - entLocalDateTime.toLocalDate().toEpochDay();
    }

    /**
     * 获取两个日期相隔几个月
     */
    public static Integer getPeriodsMonth(Long startTimestamp, Long endTimestamp) {
        if (startTimestamp == null || endTimestamp == null) {
            return null;
        }
        LocalDateTime startLocalDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(startTimestamp), ZoneId.systemDefault());
        LocalDateTime entLocalDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(endTimestamp), ZoneId.systemDefault());

        Period period = Period.between(startLocalDateTime.toLocalDate().plusDays(-1), entLocalDateTime.toLocalDate());
        return period.getYears() * 12 + period.getMonths();
    }

    /**
     * 获取两个日期相隔几年、几个月、几天
     */
    public static Map<String, Integer> getPeriods(Long startTimestamp, Long endTimestamp) {
        if (startTimestamp == null || endTimestamp == null) {
            return null;
        }
        Map<String, Integer> resultMap = new HashMap<>();
        LocalDateTime startLocalDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(startTimestamp), ZoneId.systemDefault());
        LocalDateTime entLocalDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(endTimestamp), ZoneId.systemDefault());

        Period period = Period.between(startLocalDateTime.toLocalDate().plusDays(-1), entLocalDateTime.toLocalDate());
        resultMap.put("years", period.getYears());
        resultMap.put("months", period.getMonths());
        resultMap.put("totalMonths", period.getYears() * 12 + period.getMonths());
        resultMap.put("days", period.getDays());
        return resultMap;
    }

    /**
     * 获取两个日期相隔几年、几个月、几天
     */
    public static Map<String, Integer> getPeriods(LocalDate startLocalDate, LocalDate entLocalDate) {
        if (startLocalDate == null || entLocalDate == null) {
            return null;
        }
        Map<String, Integer> resultMap = new HashMap<>();

        Period period = Period.between(startLocalDate.plusDays(-1), entLocalDate);
        resultMap.put("years", period.getYears());
        resultMap.put("months", period.getMonths());
        resultMap.put("totalMonths", period.getYears() * 12 + period.getMonths());
        resultMap.put("days", period.getDays());
        return resultMap;
    }

    /**
     * 给一个日期增加或减少相应日期
     */
    public static Long endTimestamp(Long startTimestamp, Integer year, Integer month, Integer day, Integer hour, Integer minute, Integer second) {
        if (startTimestamp == null) {
            return null;
        }
        LocalDateTime startLocalDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(startTimestamp), ZoneId.systemDefault());
        if (year != null) {
            startLocalDateTime = startLocalDateTime.plusYears(year);
        }
        if (month != null) {
            startLocalDateTime = startLocalDateTime.plusMonths(month);
        }
        if (day != null) {
            startLocalDateTime = startLocalDateTime.plusDays(day);
        }
        if (hour != null) {
            startLocalDateTime = startLocalDateTime.plusHours(hour);
        }
        if (minute != null) {
            startLocalDateTime = startLocalDateTime.plusMinutes(minute);
        }
        if (second != null) {
            startLocalDateTime = startLocalDateTime.plusSeconds(second);
        }
        return startLocalDateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
    }

    /**
     * 给一个日期增加或减少相应日期
     */
    public static Long endTimestamp(Long startTimestamp, Integer month) {
        if (startTimestamp == null) {
            return null;
        }
        LocalDateTime startLocalDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(startTimestamp), ZoneId.systemDefault());
        if (month != null) {
            startLocalDateTime = startLocalDateTime.plusMonths(month);
        }
        return startLocalDateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
    }

    /**
     * LocalDateTime 转 Long
     */
    public static Long localDateTime2Long(LocalDateTime localDateTime) {
        if (localDateTime == null) {
            return null;
        }
        return localDateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
    }

    /**
     * Long 转 LocalDateTime
     */
    public static LocalDateTime long2LocalDateTime(Long timestamp) {
        if (timestamp == null) {
            return null;
        }
        return LocalDateTime.ofInstant(Instant.ofEpochMilli(timestamp), ZoneId.systemDefault());
    }

    /**
     * 格式化日期
     */
    public static String ofPattern(Long timestamp, String format) {
        if (timestamp == null || StringUtils.isBlank(format)) {
            return null;
        }
        try {
            DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(format);
            LocalDateTime localDateTime = SystemDateUtils.long2LocalDateTime(timestamp);
            return localDateTime.format(dateTimeFormatter);
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 格式化日期
     */
    public static String ofPattern(LocalDateTime localDateTime, String format) {
        if (localDateTime == null || StringUtils.isBlank(format)) {
            return null;
        }
        try {
            DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(format);
            return localDateTime.format(dateTimeFormatter);
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 比较时间先后，startLocalDate是否先于entLocalDate
     */
    public static Boolean compare(Long localDate1, Long localDate2) {
        if (localDate1 == null || localDate2 == null) {
            return null;
        }
        LocalDateTime localDateTime1 = SystemDateUtils.long2LocalDateTime(localDate1);
        LocalDateTime localDateTime2 = SystemDateUtils.long2LocalDateTime(localDate2);
        return localDateTime1.isBefore(localDateTime2);
    }

    /**
     * 比较时间先后，startLocalDate是否先于entLocalDate
     */
    public static Boolean compare(LocalDateTime localDate1, LocalDateTime localDate2) {
        if (localDate1 == null || localDate2 == null) {
            return null;
        }
        return localDate1.isBefore(localDate2);
    }

    /**
     * 比较时间先后，startLocalDate是否先于entLocalDate
     */
    public static Boolean compareOrEquals(Long localDate1, Long localDate2) {
        if (localDate1 == null || localDate2 == null) {
            return null;
        }
        LocalDateTime localDateTime1 = SystemDateUtils.long2LocalDateTime(localDate1);
        LocalDateTime localDateTime2 = SystemDateUtils.long2LocalDateTime(localDate2);
        return localDateTime1.compareTo(localDateTime2) <= 0;
    }

    /**
     * 比较时间先后，startLocalDate是否先于entLocalDate
     */
    public static Boolean compareOrEqualsDay(Long localDate1, Long localDate2) {
        if (localDate1 == null || localDate2 == null) {
            return null;
        }
        LocalDateTime localDateTime1 = SystemDateUtils.long2LocalDateTime(localDate1);
        LocalDateTime localDateTime2 = SystemDateUtils.long2LocalDateTime(localDate2);
        return localDateTime1.toLocalDate().compareTo(localDateTime2.toLocalDate()) <= 0;
    }

    /**
     * 比较时间先后，startLocalDate是否先于entLocalDate
     */
    public static Boolean compareOrEqualsDay(LocalDateTime localDate1, LocalDateTime localDate2) {
        if (localDate1 == null || localDate2 == null) {
            return null;
        }
        return localDate1.compareTo(localDate2) <= 0;
    }

    /**
     * 比较时间先后，startLocalDate是否等于entLocalDate
     */
    public static Boolean equalsDay(LocalDateTime localDate1, LocalDateTime localDate2) {
        if (localDate1 == null || localDate2 == null) {
            return null;
        }
        return localDate1.compareTo(localDate2) == 0;
    }

    /**
     * 比较时间先后，startLocalDate是否等于entLocalDate
     */
    public static Boolean equalsDay(Long localDate1, Long localDate2) {
        if (localDate1 == null || localDate2 == null) {
            return null;
        }
        LocalDateTime localDateTime1 = SystemDateUtils.long2LocalDateTime(localDate1);
        LocalDateTime localDateTime2 = SystemDateUtils.long2LocalDateTime(localDate2);
        return localDateTime1.toLocalDate().compareTo(localDateTime2.toLocalDate()) == 0;
    }

    /**
     * 比较时间先后，startLocalDate是否先于entLocalDate
     */
    public static Long dayLastTime(LocalDateTime localDateTime) {
        if (localDateTime == null) {
            return null;
        }
        return SystemDateUtils.localDateTime2Long(LocalDateTime.of(localDateTime.toLocalDate(), LocalTime.MAX));
    }

    /**
     * 比较时间先后，startLocalDate是否先于entLocalDate
     */
    public static Long dayLastTime(Long timestamp) {
        if (timestamp == null) {
            return null;
        }
        return SystemDateUtils.localDateTime2Long(LocalDateTime.of(SystemDateUtils.long2LocalDateTime(timestamp).toLocalDate(), LocalTime.MAX));
    }

    /**
     * 字符串转换成 格式日期
     * @param s
     * @return
     */
    public  static Date convertFromDate(String s) {
        SimpleDateFormat sf=new SimpleDateFormat("yyyy-MM-dd");
        if(s == null){
            return null;
        }
        try {
            Date date=sf.parse(s);
            return date;
        }catch (Exception ex){
            return null;
        }
    }

    /**
     * 字符串转换成 格式时间
     * @param s
     * @return
     */
    public static Date convertFromDateTime(String s) {
        SimpleDateFormat sf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        if(s == null){
            return null;
        }
        try {
            Date date=sf.parse(s);
            return date;
        }catch (Exception ex){
            return null;
        }
    }

    /**
     * 格式化日期 yyyy-MM-dd HH:mm:ss
     */
    public static String ofPatternDateTime(Long timestamp) {
        String format="yyyy-MM-dd HH:mm:ss";
        if (timestamp == null || StringUtils.isBlank(format)) {
            return null;
        }
        try {
            DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(format);
            LocalDateTime localDateTime = SystemDateUtils.long2LocalDateTime(timestamp);
            return localDateTime.format(dateTimeFormatter);
        } catch (Exception e) {
            return null;
        }
    }
    /**
     * 格式化日期 yyyy-MM-dd
     */
    public static String ofPatternDate(Long timestamp) {
        String format="yyyy-MM-dd";
        if (timestamp == null || StringUtils.isBlank(format)) {
            return null;
        }
        try {
            DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(format);
            LocalDateTime localDateTime = SystemDateUtils.long2LocalDateTime(timestamp);
            return localDateTime.format(dateTimeFormatter);
        } catch (Exception e) {
            return null;
        }
    }
}
